/**
 * 用户模型
 * User Model
 */

const BaseModel = require('./BaseModel');
const bcrypt = require('bcryptjs');
const config = require('../../config/config');
const logger = require('../../utils/logger');

class User extends BaseModel {
  constructor() {
    super('users');
  }

  /**
   * 根据邮箱查找用户
   */
  async findByEmail(email) {
    try {
      return await this.findOne({ email });
    } catch (error) {
      logger.error('根据邮箱查找用户失败 / Failed to find user by email', {
        email,
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 创建用户
   */
  async createUser(userData) {
    try {
      // 检查邮箱是否已存在
      const existingUser = await this.findByEmail(userData.email);
      if (existingUser) {
        throw new Error('邮箱已存在 / Email already exists');
      }

      // 加密密码
      const hashedPassword = await bcrypt.hash(userData.password, config.security.bcryptRounds);

      // 准备用户数据
      const userToCreate = {
        email: userData.email,
        password: hashedPassword,
        nickname: userData.nickname,
        role: userData.role || 'user',
        storage_limit: userData.storage_limit || config.storage.defaultLimit,
        is_active: userData.is_active !== undefined ? userData.is_active : 1
      };

      // 如果有头像，添加头像路径
      if (userData.avatar) {
        userToCreate.avatar = userData.avatar;
      }

      const user = await this.create(userToCreate);
      
      // 返回用户信息时不包含密码
      delete user.password;
      
      logger.info('用户创建成功 / User created successfully', {
        userId: user.id,
        email: user.email
      });

      return user;
    } catch (error) {
      logger.error('创建用户失败 / Failed to create user', {
        email: userData.email,
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 验证用户密码
   */
  async validatePassword(email, password) {
    try {
      const user = await this.findByEmail(email);
      if (!user) {
        return null;
      }

      // 检查账户是否激活
      if (!user.is_active) {
        throw new Error('账户已被禁用 / Account is disabled');
      }

      const isValid = await bcrypt.compare(password, user.password);
      if (!isValid) {
        return null;
      }

      // 更新最后登录信息
      await this.updateLastLogin(user.id);

      // 返回用户信息时不包含密码
      delete user.password;
      return user;
    } catch (error) {
      logger.error('验证用户密码失败 / Failed to validate user password', {
        email,
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 更新最后登录信息
   */
  async updateLastLogin(userId, ipAddress = null) {
    try {
      const updateData = {
        last_login_at: new Date()
      };

      if (ipAddress) {
        updateData.last_login_ip = ipAddress;
      }

      await this.update(userId, updateData);
    } catch (error) {
      logger.error('更新最后登录信息失败 / Failed to update last login info', {
        userId,
        error: error.message
      });
      // 不抛出错误，因为这不是关键操作
    }
  }

  /**
   * 更新用户密码
   */
  async updatePassword(userId, newPassword) {
    try {
      const hashedPassword = await bcrypt.hash(newPassword, config.security.bcryptRounds);
      
      await this.update(userId, {
        password: hashedPassword,
        updated_at: new Date()
      });

      logger.info('用户密码更新成功 / User password updated successfully', {
        userId
      });

      return true;
    } catch (error) {
      logger.error('更新用户密码失败 / Failed to update user password', {
        userId,
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 更新用户存储使用量
   */
  async updateStorageUsed(userId, storageUsed) {
    try {
      await this.update(userId, {
        storage_used: storageUsed,
        updated_at: new Date()
      });

      logger.debug('用户存储使用量更新成功 / User storage usage updated successfully', {
        userId,
        storageUsed
      });

      return true;
    } catch (error) {
      logger.error('更新用户存储使用量失败 / Failed to update user storage usage', {
        userId,
        storageUsed,
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 获取用户存储统计
   */
  async getStorageStats(userId) {
    try {
      const user = await this.findById(userId, 'storage_used, storage_limit');
      if (!user) {
        throw new Error('用户不存在 / User not found');
      }

      const usagePercentage = (user.storage_used / user.storage_limit) * 100;
      const remainingStorage = user.storage_limit - user.storage_used;

      return {
        used: user.storage_used,
        limit: user.storage_limit,
        remaining: remainingStorage,
        usagePercentage: Math.round(usagePercentage * 100) / 100,
        isNearLimit: usagePercentage > (config.storage.warningThreshold * 100),
        isOverLimit: usagePercentage > (config.storage.maxThreshold * 100)
      };
    } catch (error) {
      logger.error('获取用户存储统计失败 / Failed to get user storage stats', {
        userId,
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 获取活跃用户列表
   */
  async getActiveUsers(options = {}) {
    try {
      const conditions = { is_active: 1 };
      return await this.findMany(conditions, {
        fields: 'id, email, nickname, role, storage_used, storage_limit, last_login_at, created_at',
        ...options
      });
    } catch (error) {
      logger.error('获取活跃用户列表失败 / Failed to get active users', {
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 获取管理员用户列表
   */
  async getAdminUsers() {
    try {
      return await this.findMany(
        { role: 'admin', is_active: 1 },
        {
          fields: 'id, email, nickname, last_login_at, created_at',
          orderBy: 'created_at ASC'
        }
      );
    } catch (error) {
      logger.error('获取管理员用户列表失败 / Failed to get admin users', {
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 禁用用户账户
   */
  async disableUser(userId) {
    try {
      await this.update(userId, {
        is_active: 0,
        updated_at: new Date()
      });

      logger.info('用户账户已禁用 / User account disabled', { userId });
      return true;
    } catch (error) {
      logger.error('禁用用户账户失败 / Failed to disable user account', {
        userId,
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 启用用户账户
   */
  async enableUser(userId) {
    try {
      await this.update(userId, {
        is_active: 1,
        updated_at: new Date()
      });

      logger.info('用户账户已启用 / User account enabled', { userId });
      return true;
    } catch (error) {
      logger.error('启用用户账户失败 / Failed to enable user account', {
        userId,
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 获取用户统计信息
   */
  async getUserStats() {
    try {
      const sql = `
        SELECT 
          COUNT(*) as total_users,
          COUNT(CASE WHEN is_active = 1 THEN 1 END) as active_users,
          COUNT(CASE WHEN role = 'admin' THEN 1 END) as admin_users,
          COUNT(CASE WHEN last_login_at > DATE_SUB(NOW(), INTERVAL 30 DAY) THEN 1 END) as recent_active_users,
          SUM(storage_used) as total_storage_used,
          AVG(storage_used) as avg_storage_used
        FROM users
      `;

      const { rows } = await this.raw(sql);
      return rows[0];
    } catch (error) {
      logger.error('获取用户统计信息失败 / Failed to get user statistics', {
        error: error.message
      });
      throw error;
    }
  }

  /**
   * 搜索用户
   */
  async searchUsers(keyword, options = {}) {
    try {
      const { page = 1, pageSize = 20 } = options;
      const offset = (page - 1) * pageSize;

      const sql = `
        SELECT id, email, nickname, role, is_active, last_login_at, created_at
        FROM users 
        WHERE (email LIKE ? OR nickname LIKE ?)
        ORDER BY created_at DESC
        LIMIT ? OFFSET ?
      `;

      const searchTerm = `%${keyword}%`;
      const { rows } = await this.raw(sql, [searchTerm, searchTerm, pageSize, offset]);

      // 获取总数
      const countSql = `
        SELECT COUNT(*) as total 
        FROM users 
        WHERE (email LIKE ? OR nickname LIKE ?)
      `;
      const { rows: countRows } = await this.raw(countSql, [searchTerm, searchTerm]);
      const total = countRows[0].total;

      return {
        data: rows,
        pagination: {
          page,
          pageSize,
          total,
          totalPages: Math.ceil(total / pageSize)
        }
      };
    } catch (error) {
      logger.error('搜索用户失败 / Failed to search users', {
        keyword,
        error: error.message
      });
      throw error;
    }
  }
}

module.exports = new User();